import {AnyFunction} from "./function"


/**
 * 获取对象的方法的某个参数的类型
 * 
 * @typeParam Obj - 对象
 * @typeParam Method - 对象方法的名字
 * @typeParam ParamIndex - 参数的索引个数
 */
export type MethodParams<Obj,Method extends keyof Obj,ParamIndex extends number> = Obj[Method] extends AnyFunction ? Parameters<Obj[Method]>[ParamIndex] : never;




/**
 * 获取对象的方法的返回的类型
 * 
 * @typeParam Obj - 对象
 * @typeParam Method - 对象方法的名字
 */
 export type MethodReturnType<Obj,Method extends keyof Obj> = Obj[Method] extends AnyFunction ? ReturnType<Obj[Method]>: never;


 /**
  * 获取数组元素的类型
  * @typeParam Arr 数组
  */
 export type ArrayItemType<Arr> = Arr extends (infer Item)[] ? Item : never;




/**
 * 格式化为数组格式
 * @remarks
 * 如果 ItemOrArray 是数组，则保持不变
 * 如果  ItemOrArray 不是数组，则转为数组类型 ItemOrArray[]
 */
export type FormatAsArray<ItemOrArray> = ItemOrArray extends any[] ? ItemOrArray : ItemOrArray[];


/**
 * 格式化为数组格式
 * @remarks
 * 如果 value 是数组，则保持不变
 * 如果  value 不是数组，则转为数组类型
 * @param value 
 * @returns 
 */
export function formatAsArray<V>(value:V):FormatAsArray<V>{
    // @ts-ignore
    return  Array.isArray(value) ? value : (value == null ? [] : [value]);
}


/**
 * 格式化对象成员为数组格式
 * @remarks
 * 如果 成员 是数组，则保持不变
 * 如果  成员 不是数组，则转为数组类型
 */
export type FormatMemberAsArray<D> = {[K in keyof D]:FormatAsArray<D[K]>}

/**
 * 格式化对象成员为数组格式
 * @remarks
 * 如果 成员 是数组，则保持不变
 * 如果  成员 不是数组，则转为数组类型
 * 
 * @returns 返回来的 data 对象，此方法会改变原对象 data，耗会生成新的对象
 */
export function formatMemberAsArray<D extends {}>(data:D):FormatMemberAsArray<D>{
    for (const [key,value] of Object.entries(data)){
        // @ts-ignore
        data[key] = Array.isArray(value) ? value : (value == null ? [] : [value]);
    }
    // @ts-ignore
    return data;
}